package com.tucy.logistics.modules.organization.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tucy.logistics.common.base.BaseEnum;
import com.tucy.logistics.common.entity.organization.OrganizationPosition;
import com.tucy.logistics.common.enums.AddressTypeEnum;
import com.tucy.logistics.common.result.ServiceException;
import com.tucy.logistics.modules.organization.service.OrganizationPositionService;
import com.tucy.logistics.modules.organization.mapper.OrganizationPositionMapper;
import com.tucy.logistics.utils.HttpRequestUtil;
import com.tucy.logistics.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


/**
* @author tucy123
* @description 针对表【organization_position(地理位置表)】的数据库操作Service实现
* @createDate 2023-09-15 16:10:16
*/
@Service
@CacheConfig(cacheNames = "china")
public class OrganizationPositionServiceImpl extends ServiceImpl<OrganizationPositionMapper, OrganizationPosition> implements OrganizationPositionService{

    @Autowired
    OrganizationPositionMapper positionMapper;

    @Autowired
    HttpRequestUtil httpRequestUtil;

    @Value("${geo.addressKey}")
    private String addressKey;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 更新地理位置
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "china", allEntries = true)
    public Boolean restock() {
        // 删除地理库
        positionMapper.delete(null);

        String url = "https://restapi.amap.com/v3/config/district?subdistrict=3&key=" + addressKey;

        try {
            // 获取三级地区
            String request = httpRequestUtil.huToolGetRequest(url);
            JSONObject addressJson = JSONObject.parseObject(request);

            if (BaseEnum.NORMAL.getValue().equals(Integer.valueOf(addressJson.getString("status")))) {
                // 省份
                JSONArray districts = addressJson.getJSONArray("districts");
                JSONArray provinces = JSONObject.parseObject(String.valueOf(districts.get(0))).getJSONArray("districts");
                for (Object province : provinces) {
                    JSONObject provinceJson = JSONObject.parseObject(String.valueOf(province));
                    OrganizationPosition provincePosition = new OrganizationPosition();
                    provincePosition.setParentId(Long.valueOf(AddressTypeEnum.PROVINCE.getValue()));
                    provincePosition.setType(AddressTypeEnum.PROVINCE.getValue());
                    provincePosition.setName(provinceJson.getString("name"));
                    provincePosition.setLongitude(provinceJson.getString("center").split(",")[0]);
                    provincePosition.setLatitude(provinceJson.getString("center").split(",")[1]);
                    provincePosition.setAdcode(provinceJson.getString("adcode"));
                    this.save(provincePosition);

                    // 城市
                    List<OrganizationPosition> cityPositions = new LinkedList<>();
                    JSONArray cities = provinceJson.getJSONArray("districts");
                    for (Object city : cities) {
                        JSONObject cityJson = JSONObject.parseObject(String.valueOf(city));
                        OrganizationPosition cityPosition = new OrganizationPosition();
                        cityPosition.setParentId(provincePosition.getId());
                        cityPosition.setType(AddressTypeEnum.CITY.getValue());
                        cityPosition.setName(cityJson.getString("name"));
                        cityPosition.setLongitude(cityJson.getString("center").split(",")[0]);
                        cityPosition.setLatitude(cityJson.getString("center").split(",")[1]);
                        cityPosition.setAdcode(cityJson.getString("adcode"));
                        this.save(cityPosition);

                        // 区县
                        List<OrganizationPosition> countryPositions = new LinkedList<>();
                        JSONArray countries = cityJson.getJSONArray("districts");
                        for (Object country : countries) {
                            JSONObject countryJson = JSONObject.parseObject(String.valueOf(country));
                            OrganizationPosition countryPosition = new OrganizationPosition();
                            countryPosition.setParentId(cityPosition.getId());
                            countryPosition.setType(AddressTypeEnum.COUNTY.getValue());
                            countryPosition.setName(countryJson.getString("name"));
                            countryPosition.setLongitude(countryJson.getString("center").split(",")[0]);
                            countryPosition.setLatitude(countryJson.getString("center").split(",")[1]);
                            countryPosition.setAdcode(countryJson.getString("adcode"));
                            countryPositions.add(countryPosition);
                        }
                        this.saveBatch(countryPositions);
                    }
                }
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new ServiceException("更新失败");
    }

    /**
     * 省级单位
     * @return
     */
    @Override
    @Cacheable(key = "'province:1'", unless = "#result = null")
    public List<OrganizationPosition> queryProvincePosition() {
        return this.lambdaQuery().eq(OrganizationPosition::getType,AddressTypeEnum.PROVINCE.getValue()).list();
    }

    /**
     * 省市县
     * @param provinceId
     * @return
     */
    @Override
    @Cacheable(key = "'province:'+ #provinceId", unless = "#result = null")
    public List<OrganizationPosition> queryThreePosition(Long provinceId) {
        List<OrganizationPosition> positions = this.list();

        List<OrganizationPosition> organizationPositions = positions.stream().filter(position -> position.getParentId().equals(Long.valueOf(AddressTypeEnum.PROVINCE.getValue())))
                .peek(provincePosition -> provincePosition.setChildren(getChildrenPosition(provincePosition, positions)))
                .collect(Collectors.toList());

        //缓存保存返回类型LinkedHashMap，因此结果对象为List<OrganizationPosition>，确保缓存可以有效
        return organizationPositions.stream().filter(position -> position.getId().equals(provinceId)).collect(Collectors.toList());
    }

    private List<OrganizationPosition> getChildrenPosition(OrganizationPosition provincePosition, List<OrganizationPosition> positions) {
        return positions.stream().filter(position -> position.getParentId().equals(provincePosition.getId()))
                .peek(cityPosition -> cityPosition.setChildren(getChildrenPosition(cityPosition,positions)))
                .collect(Collectors.toList());
    }

}




